package cpu.footprint.view.photo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AlphaAnimation;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ZoomControls;

import cpu.footprint.R;

public class TouchImageActivity extends Activity {
    private static final String TAG = "TouchImage";
    private static final int REQUIRED_BITMAP_SIZE = 400;
    private static final int PAGER_MARGIN_DP = 40;
    private ViewPager mViewPager;
    private TextView mPageShwo;
    private ImagePagerAdapter mPagerAdapter;
    private GestureDetector mGestureDetector;
    private ScaleGestureDetector mScaleGestureDetector;

    private boolean mPaused;
    private boolean mOnScale = false;
    private boolean mOnPagerScoll = false;
    private boolean mControlsShow = false;

    // 传入参数
    private List<String> mImageList = new ArrayList<>();
    private int mPosition;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.p_viewpager);
        mImageList = this.getIntent().getStringArrayListExtra("imgs");
        mViewPager = (ViewPager) findViewById(R.id.viewPager);
        mPageShwo = (TextView) findViewById(R.id.tv_page);
        final float scale = getResources().getDisplayMetrics().density;
        int pagerMarginPixels = (int) (PAGER_MARGIN_DP * scale + 0.5f);
        mViewPager.setPageMargin(pagerMarginPixels);
        mViewPager.setPageMarginDrawable(new ColorDrawable(Color.BLACK));

        mPagerAdapter = new ImagePagerAdapter();
        mViewPager.setAdapter(mPagerAdapter);
        mViewPager.setOnPageChangeListener(mPageChangeListener);
        setupOnTouchListeners(mViewPager);
        if (mImageList.size() == 0) {
            Builder builder = new Builder(this);
            builder.setMessage("请确保有图片，或者将imagesDir更换为有图片的路径。");
            builder.setNeutralButton("退出",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            TouchImageActivity.this.finish();
                            return;
                        }
                    });
            builder.show();
        }
        mPosition = this.getIntent().getIntExtra("index", 0);
        mViewPager.setCurrentItem(mPosition, false);
        updateShowInfo();
    }

    private void updateShowInfo() {
        if (mImageList.size() > 0) {
            mPageShwo.setText(String.format("%d/%d", mPosition + 1,
                    mImageList.size()));
        }
    }

    // decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = REQUIRED_BITMAP_SIZE;

            // Find the correct scale value. It should be the power of 2.
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }

    @Override
    public void onStart() {
        super.onStart();
        mPaused = false;
    }

    @Override
    public void onStop() {
        super.onStop();
        mPaused = true;
    }

    private void setupOnTouchListeners(View rootView) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
            mScaleGestureDetector = new ScaleGestureDetector(this,
                    new MyOnScaleGestureListener());
        }
        mGestureDetector = new GestureDetector(this, new MyGestureListener());

        OnTouchListener rootListener = new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                // NOTE: gestureDetector may handle onScroll..
                if (!mOnScale) {
                    if (!mOnPagerScoll) {
                        mGestureDetector.onTouchEvent(event);
                    }
                }

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
                    if (!mOnPagerScoll) {
                        mScaleGestureDetector.onTouchEvent(event);
                    }
                }

                ImageViewTouch imageView = getCurrentImageView();
                if (imageView == null) {
                    return true;
                }
                if (!mOnScale) {
                    Matrix m = imageView.getImageViewMatrix();
                    RectF rect = new RectF(0, 0, imageView.mBitmapDisplayed
                            .getBitmap().getWidth(), imageView.mBitmapDisplayed
                            .getBitmap().getHeight());
                    m.mapRect(rect);
                    // 图片超出屏幕范围后移动
                    if (!(rect.right > imageView.getWidth() + 0.1 && rect.left < -0.1)) {
                        try {
                            mViewPager.onTouchEvent(event);
                        } catch (ArrayIndexOutOfBoundsException e) {
                            // why?
                        }
                    }
                }

                // We do not use the return value of
                // mGestureDetector.onTouchEvent because we will not receive
                // the "up" event if we return false for the "down" event.
                return true;
            }
        };

        rootView.setOnTouchListener(rootListener);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent m) {
        if (mPaused)
            return true;
        return super.dispatchTouchEvent(m);
    }

    @Override
    protected void onDestroy() {
        ImageViewTouch imageView = getCurrentImageView();
        if (imageView != null) {
            imageView.mBitmapDisplayed.recycle();
            imageView.clear();
        }
        super.onDestroy();
    }

    private ImageViewTouch getCurrentImageView() {
        return (ImageViewTouch) mPagerAdapter.views.get((mViewPager
                .getCurrentItem()));
    }

    ViewPager.OnPageChangeListener mPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageSelected(int position, int prePosition) {
            // Log.d(TAG, "onPageSelected" + position + ", prePosition: "
            // + prePosition);
            ImageViewTouch preImageView = mPagerAdapter.views.get(prePosition);
            if (preImageView != null) {
                preImageView.setImageBitmapResetBase(
                        preImageView.mBitmapDisplayed.getBitmap(), true);
            }
            mPosition = position;
            updateShowInfo();
        }

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            // Log.d(TAG, "onPageScrolled");
            mOnPagerScoll = true;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            // Log.d(TAG, "onPageScrollStateChanged: " + state);
            if (state == ViewPager.SCROLL_STATE_DRAGGING) {
                mOnPagerScoll = true;
            } else if (state == ViewPager.SCROLL_STATE_SETTLING) {
                mOnPagerScoll = false;
            } else {
                mOnPagerScoll = false;
            }
        }
    };

    private class MyGestureListener extends
            GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
            // Log.d(TAG, "gesture onScroll");
            if (mOnScale) {
                return true;
            }
            if (mPaused) {
                return false;
            }
            ImageViewTouch imageView = getCurrentImageView();
            if (imageView == null) {
                return true;
            }
            imageView.panBy(-distanceX, -distanceY);
            imageView.center(true, true);

            // 超出边界效果去掉这个
            imageView.center(true, true);

            return true;
        }

        @Override
        public boolean onUp(MotionEvent e) {
            return super.onUp(e);
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            if (mControlsShow) {
                // delayHideControls();
                //hideControls();
            } else {
//				updateZoomButtonsEnabled();
//				showControls();
            }
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            if (mPaused) {
                return false;
            }
            ImageViewTouch imageView = getCurrentImageView();
            if (imageView == null) {
                return true;
            }
            // Switch between the original scale and 3x scale.
            if (imageView.mBaseZoom < 1) {
                if (imageView.getScale() > 2F) {
                    imageView.zoomTo(1f);
                } else {
                    imageView.zoomToPoint(3f, e.getX(), e.getY());
                }
            } else {
                if (imageView.getScale() > (imageView.mMinZoom + imageView.mMaxZoom) / 2f) {
                    imageView.zoomTo(imageView.mMinZoom);
                } else {
                    imageView.zoomToPoint(imageView.mMaxZoom, e.getX(),
                            e.getY());
                }
            }
            return true;
        }
    }

    private class MyOnScaleGestureListener extends
            ScaleGestureDetector.SimpleOnScaleGestureListener {

        float currentScale;
        float currentMiddleX;
        float currentMiddleY;

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            final ImageViewTouch imageView = getCurrentImageView();
            if (imageView == null) {
                return;
            }

            Log.d(TAG, "currentScale: " + currentScale + ", maxZoom: "
                    + imageView.mMaxZoom);
            if (currentScale > imageView.mMaxZoom) {
                imageView
                        .zoomToNoCenterWithAni(currentScale
                                        / imageView.mMaxZoom, 1, currentMiddleX,
                                currentMiddleY);
                currentScale = imageView.mMaxZoom;
                imageView.zoomToNoCenterValue(currentScale, currentMiddleX,
                        currentMiddleY);
            } else if (currentScale < imageView.mMinZoom) {
                imageView.zoomToNoCenterWithAni(currentScale,
                        imageView.mMinZoom, currentMiddleX, currentMiddleY);
                currentScale = imageView.mMinZoom;
                imageView.zoomToNoCenterValue(currentScale, currentMiddleX,
                        currentMiddleY);
            } else {
                imageView.zoomToNoCenter(currentScale, currentMiddleX,
                        currentMiddleY);
            }

            imageView.center(true, true);

            // NOTE: 延迟修正缩放后可能移动问题
            imageView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mOnScale = false;
                }
            }, 300);
            // Log.d(TAG, "gesture onScaleEnd");
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            // Log.d(TAG, "gesture onScaleStart");
            mOnScale = true;
            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector, float mx, float my) {
            // Log.d(TAG, "gesture onScale");
            ImageViewTouch imageView = getCurrentImageView();
            if (imageView == null) {
                return true;
            }
            float ns = imageView.getScale() * detector.getScaleFactor();

            currentScale = ns;
            currentMiddleX = mx;
            currentMiddleY = my;

            if (detector.isInProgress()) {
                imageView.zoomToNoCenter(ns, mx, my);
            }
            return true;
        }
    }

    private class ImagePagerAdapter extends PagerAdapter {
        public Map<Integer, ImageViewTouch> views = new HashMap<Integer, ImageViewTouch>();

        @Override
        public int getCount() {
            // Log.d(TAG, "getCount");
            return mImageList.size();
        }

        @Override
        public Object instantiateItem(final View container, final int position) {
            // Log.d(TAG, "instantiateItem");
            final ImageViewTouch imageView = new ImageViewTouch(
                    TouchImageActivity.this);
            imageView.setLayoutParams(new LayoutParams(
                    LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
            imageView.setBackgroundColor(Color.BLACK);
            imageView.setFocusableInTouchMode(true);

            Bitmap b;
//			b=returnBitmap();
            final String url = mImageList.get(position);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    URL fileUrl = null;
                    Bitmap bitmap = null;
                    try {
                        fileUrl = new URL(url);
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (fileUrl == null) {
                            fileUrl = new URL(url);
                        }
                        HttpURLConnection conn = (HttpURLConnection) fileUrl
                                .openConnection();
                        conn.setDoInput(true);
                        conn.connect();
                        InputStream is = conn.getInputStream();
                        bitmap = BitmapFactory.decodeStream(is);
                        final Bitmap finalBitmap = bitmap;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                imageView.setImageBitmapResetBase(finalBitmap, true);
                                ((ViewPager) container).addView(imageView);
                                views.put(position, imageView);
                            }
                        });
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            return imageView;
        }

        @Override
        public void destroyItem(View container, int position, Object object) {
            // Log.d(TAG, "destroyItem");
            ImageViewTouch imageView = (ImageViewTouch) object;
            imageView.mBitmapDisplayed.recycle();
            imageView.clear();
            ((ViewPager) container).removeView(imageView);
            views.remove(position);
        }

        @Override
        public void startUpdate(View container) {
            // Log.d(TAG, "startUpdate");
        }

        @Override
        public void finishUpdate(View container) {
            // Log.d(TAG, "finishUpdate");
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            // Log.d(TAG, "isViewFromObject");
            return view == ((ImageViewTouch) object);
        }

        @Override
        public Parcelable saveState() {
            // Log.d(TAG, "saveState");
            return null;
        }

        @Override
        public void restoreState(Parcelable state, ClassLoader loader) {
            // Log.d(TAG, "restoreState");
        }
    }

    /**
     * 根据图片的url路径获得Bitmap对象
     *
     * @param url
     * @return
     */
    private void returnBitmap(final String url) {
        Log.d(TAG, "---Url:" + url);

    }

    private Uri getCurrentImageUri() {
        File file = new File(mImageList.get(mPosition));
        return Uri.fromFile(file);
    }
}
